/**
 * 
 */
package com.jcode.skeleton.util;

import java.util.concurrent.Executors;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;

/**
 * 
 * @Desc Guava EventBus事件总线工厂
 * 
 *       <pre>
 *   使用方法：
 *       1.编写事件监听器EventListener，在方法上面添加注解@Subscribe注册感兴趣的事件，方法的参数为事件源。
 *       2.使用注解@AllowConcurrentEvents声明监听器方法线程安全（注意监听器成员变量），允许并发调用，能提高执行效率，
 *       否则Guava会使用Synchronize进行同步方式处理。
 *       3.注册监听器registerXXXEventListener。
 *       4.接收事件通知。
 * 
 *   EventBus支持同步和异步事件通知。
 *   事件通知：
 *       1.同步事件通知，调用方法postEventSync，同步监听器进行事件处理。
 *       2.异步事件通知，调用方法postEventAsync，异步监听器进行事件处理。
 * 
 *   注册监听器：
 *       1.注册同步监听器，调用方法registerSyncEventListener，只接收同步发送事件，调用事件通知方法postEventSync时处理。
 *       2.注册异步监听器，调用方法registerAsyncEventListener，只接收异步发送事件，调用事件通知方法postEventAsync时处理。
 *       3.注册同步和异步监听器，调用方法registerEventListener，可接收同步和异步发送事件，根据事件通知方式不同进行自动选择同步监听器还是异步监听器。
 * </pre>
 * @Author dreajay
 * @DateTime 2016年10月10日 上午11:00:07
 *
 */
public class EventBusFactory {

	/** 同步事件总线 */
	private final EventBus eventBus = new EventBus();
	/** 异步事件总线 */
	private final AsyncEventBus asyncEventBus = new AsyncEventBus(Executors.newCachedThreadPool(new NamedThreadFactory("eventBus-thread")));

	private EventBusFactory() {
	}

	// 私有静态
	private static final class Holder {
		// static final Singleton
		private static final EventBusFactory INSTANCE = new EventBusFactory();
	}

	public static EventBusFactory getInstance() {
		return Holder.INSTANCE;
	}

	/**
	 * 注册同步和异步事件监听器
	 * 
	 * @param eventListener
	 */
	public void registerEventListener(Object eventListener) {
		eventBus.register(eventListener);
		asyncEventBus.register(eventListener);
	}

	/**
	 * 注销同步和异步事件监听器
	 * 
	 * @param eventListener
	 */
	public void unregisterEventListener(Object eventListener) {
		eventBus.unregister(eventListener);
		asyncEventBus.unregister(eventListener);
	}

	/**
	 * 注册同步事件监听器
	 * 
	 * @param eventListener
	 */
	public void registerSyncEventListener(Object eventListener) {
		eventBus.register(eventListener);
	}

	/**
	 * 注销同步事件监听器
	 * 
	 * @param eventListener
	 */
	public void unregisterSyncEventListener(Object eventListener) {
		eventBus.unregister(eventListener);
	}

	/**
	 * 注册异步事件监听器
	 * 
	 * @param eventListener
	 */
	public void registerAsyncEventListener(Object eventListener) {
		asyncEventBus.register(eventListener);
	}

	/**
	 * 注销异步事件监听器
	 * 
	 * @param eventListener
	 */
	public void unregisterAsyncEventListener(Object eventListener) {
		asyncEventBus.unregister(eventListener);
	}

	/**
	 * 同步发送事件
	 * 
	 * @param event
	 */
	public void postEventSync(Object event) {
		eventBus.post(event);
	}

	/**
	 * 异步发送事件
	 * 
	 * @param event
	 */
	public void postEventAsync(Object event) {
		asyncEventBus.post(event);
	}

}